﻿/*
	Copyright (C) 2019 Zongming Liu <1849059316@qq.com>

	This program is free software; you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation; either version 2 of the License, or
	(at your option) any later version.
	
	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.
	
	You should have received a copy of the GNU General Public License along
	with this program; if not, write to the Free Software Foundation, Inc.,
	51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#include "Camera.h"
#include "../win32/ApplicationView.h"
#include "../base/GameWorld.h"

namespace SkyEngine2d
{
	
	Camera * Camera::CreateCamera(float view_width, float view_hight, float near_plane, float far_plane)
	{
		auto c = new Camera();
		if (c&&c->init(view_width, view_hight, near_plane, far_plane))
		{
			return c;
		}
		delete c;
		return nullptr;
	}
	
	void Camera::moveCarme(const Vector2 & dt)
	{
		m_positionX=m_focus.x+=dt.x;
		m_positionY=m_focus.y += dt.y;
		m_isChangeVpMat = true;
	}
	
	void Camera::updataCarme()
	{
		if (m_isChangeVpMat)
		{
			auto pitch = 0 * 0.0174532925f;
			auto yaw =  0* 0.0174532925f;
			auto roll = 0 * 0.0174532925f;
	
			auto rotationMat = DirectX::XMMatrixRotationRollPitchYaw(pitch, yaw, roll);
			Vector3 lookAt = XMVector3TransformCoord(Vector3(m_focus.x, m_focus.y, 0.0f), rotationMat);
			Vector3 up = XMVector3TransformCoord(Vector3(0.0f, 1.0f, 0.0f), rotationMat);
	
			m_viewMatrix = DirectX::XMMatrixLookAtLH(Vector3(m_positionX, m_positionY, -1.0f),
				lookAt,
				up);
			
			m_vpMat = DirectX::XMMatrixMultiply(m_viewMatrix, m_projectionMatrix);
			m_isChangeVpMat = false;
		}
	}
	
	Camera * Camera::getDefultCamera()
	{
		static Camera * c = nullptr;
		if (c)
		{
			return c;
		}
		auto size = GameWorld::getInstance()->getAppView()->getViewSize();
		c = Camera::CreateCamera(size.width, size.height, 1, 1000);
		return c;
	}
	
	void Camera::setPosition(float x, float y)
	{
		 m_focus = Vector2(x, y); 
		 m_isChangeVpMat = true; 
		 m_positionX = m_focus.x;
		 m_positionY = m_focus.y;
	}
	
	Vector2 Camera::getPostion() const
	{
		return m_focus;
	}
	
	
	Camera::Camera()
		:m_isChangeVpMat(false)
		,m_positionX(0)
		,m_positionY(0)
		,m_rotationZ(0)
	{
	
	}
	
	bool Camera::init(float view_width, float view_hight, float near_plane, float far_plane)
	{
	
		auto pitch = 0 * 0.0174532925f;
		auto yaw =  0* 0.0174532925f;
		auto roll = 0 * 0.0174532925f;
	
		auto rotationMat = DirectX::XMMatrixRotationRollPitchYaw(pitch, yaw, roll);
		auto lookAt = XMVector3TransformCoord(Vector3(m_focus.x, m_focus.y,0.0f), rotationMat);
		auto up = XMVector3TransformCoord(Vector3(0.0f, 1.0f, 0.0f), rotationMat);
	
		m_viewMatrix = DirectX::XMMatrixLookAtLH(Vector3(m_positionX, m_positionY, -1.0f),
			lookAt,
			up);
	
		m_projectionMatrix = DirectX::XMMatrixOrthographicOffCenterLH(0.0f, view_width, 0.0f, view_hight, near_plane, far_plane);
		m_vpMat = DirectX::XMMatrixMultiply(m_viewMatrix, m_projectionMatrix);
	
		return true;
	}
	
}
